﻿using System;
using System.Data;
using MySql.Data.MySqlClient;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.UI;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using System.Collections.Generic;

namespace Demo
{
    public partial class DataList2 : Form
    {
        private const char CurrentFType = 'B';
        private const string ReportDirectory = "Reports";

        public DataList2()
        {
            InitializeComponent();
            TraditionalChineseHelper.Apply(this);
            ApplyBlueTheme();
            ConfigureToolbarButtons();
            ConfigureContextMenuIcons();
            ConfigureGridColumns();

            bandedGridView1.DoubleClick += BandedGridView1_DoubleClick;
            toolStripButton7.Click += toolStripButton7_Click;
            toolStripButtonExportReport.Click += toolStripButtonExportReport_Click;
            toolStripButtonViewReport.Click += toolStripButtonViewReport_Click;
        }

        private void ApplyBlueTheme()
        {
            BackColor = Color.FromArgb(227, 239, 255);

            toolStrip1.BackColor = Color.FromArgb(194, 217, 247);
            toolStrip1.RenderMode = ToolStripRenderMode.System;
            toolStrip1.ImageScalingSize = new Size(20, 20);

            gridControl1.LookAndFeel.UseDefaultLookAndFeel = false;
            gridControl1.LookAndFeel.SkinName = "Office 2010 Blue";
        }

        private void ConfigureToolbarButtons()
        {
            ConfigureButton(toolStripButton3, IconFactory.RefreshIcon);
            ConfigureButton(toolStripButton4, IconFactory.ExportIcon);
            ConfigureButton(toolStripButton5, IconFactory.AddIcon);
            ConfigureButton(toolStripButton6, IconFactory.EditIcon);
            ConfigureButton(toolStripButton7, IconFactory.DeleteIcon);
            ConfigureButton(toolStripButtonExportReport, IconFactory.ReportExportIcon);
            ConfigureButton(toolStripButtonViewReport, IconFactory.ReportViewIcon);
        }

        private void ConfigureContextMenuIcons()
        {
            刷新ToolStripMenuItem.Image = IconFactory.RefreshIcon;
            toolStripMenuItem2.Image = IconFactory.AddIcon;
            toolStripMenuItem1.Image = IconFactory.EditIcon;
            删除ToolStripMenuItem.Image = IconFactory.DeleteIcon;
        }

        private static void ConfigureButton(ToolStripButton button, Image image)
        {
            button.Image = image;
            button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
            button.TextImageRelation = TextImageRelation.ImageBeforeText;
            button.ImageAlign = ContentAlignment.MiddleLeft;
        }

        private void ConfigureGridColumns()
        {
            GridColumnFactory.ConfigureCommonColumns(bandedGridView1);
        }

        private void PPCRM_Stock_Load(object sender, EventArgs e)
        {
            getData();
        }

        private void getData()
        {
            try
            {
                using var connection = new MySqlConnection(DatabaseConfig.ConnectionString);
                using var command = new MySqlCommand("usp_GetTestEntries", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };
                command.Parameters.AddWithValue("@p_FType", CurrentFType);

                using var adapter = new MySqlDataAdapter(command);
                var table = new DataTable();
                connection.Open();
                MySqlCollationHelper.EnsureGeneralCollation(connection);
                adapter.Fill(table);
                GridDataHelper.PrepareDataTable(table);
                gridControl1.DataSource = table;
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"載入資料失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private static string? FetchReportPassword(int entryId)
        {
            try
            {
                using var connection = new MySqlConnection(DatabaseConfig.ConnectionString);
                using var command = new MySqlCommand("SELECT ReportPassword FROM TestEntries WHERE EntryID = @EntryID", connection);
                command.Parameters.AddWithValue("@EntryID", entryId);

                connection.Open();
                MySqlCollationHelper.EnsureGeneralCollation(connection);
                var result = command.ExecuteScalar();
                if (result == null || result == DBNull.Value)
                {
                    return null;
                }

                var decrypted = ReportPasswordProtector.Decrypt(result.ToString()!);
                return string.IsNullOrEmpty(decrypted) ? null : decrypted;
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"獲取報告密碼失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                return null;
            }
        }

        private int? GetFocusedEntryId()
        {
            if (bandedGridView1.FocusedRowHandle < 0)
            {
                return null;
            }

            var value = bandedGridView1.GetFocusedRowCellValue("EntryID");
            if (value == null || value == DBNull.Value)
            {
                return null;
            }

            return int.TryParse(value.ToString(), out var id) ? id : null;
        }

        private void DeleteEntry(int entryId)
        {
            try
            {
                using var connection = new MySqlConnection(DatabaseConfig.ConnectionString);
                using var command = new MySqlCommand("usp_DeleteTestEntry", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };
                command.Parameters.AddWithValue("@p_EntryID", entryId);

                var resultCodeParam = new MySqlParameter("@p_ResultCode", MySqlDbType.Int32)
                {
                    Direction = ParameterDirection.Output
                };
                var resultMessageParam = new MySqlParameter("@p_ResultMessage", MySqlDbType.VarChar, 200)
                {
                    Direction = ParameterDirection.Output
                };
                command.Parameters.Add(resultCodeParam);
                command.Parameters.Add(resultMessageParam);

                connection.Open();
                MySqlCollationHelper.EnsureGeneralCollation(connection);
                command.ExecuteNonQuery();

                var resultCode = resultCodeParam.Value != DBNull.Value ? Convert.ToInt32(resultCodeParam.Value) : 0;
                var resultMessage = resultMessageParam.Value?.ToString();

                if (resultCode != 0)
                {
                    var fallback = TraditionalChineseHelper.Convert("刪除失敗，請稍後再試。");
                    var message = string.IsNullOrWhiteSpace(resultMessage)
                        ? fallback
                        : TraditionalChineseHelper.Convert(resultMessage);
                    XtraMessageBox.Show(
                        message,
                        TraditionalChineseHelper.Convert("刪除失敗"),
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    return;
                }

                getData();
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"刪除資料失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            getData();
        }

        private void gridView1_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.Info.IsRowIndicator && e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString();
            }
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            using var dialog = new SaveFileDialog
            {
                Title = TraditionalChineseHelper.Convert("導出 Excel"),
                Filter = TraditionalChineseHelper.Convert("Excel 文件 (*.xlsx)|*.xlsx"),
                FileName = TraditionalChineseHelper.Convert($"測試資料_{DateTime.Now:yyyyMMddHHmm}.xlsx")
            };

            if (dialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            try
            {
                gridControl1.ExportToXlsx(dialog.FileName);
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("導出成功。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"導出失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void BandedGridView1_DoubleClick(object sender, EventArgs e)
        {
            var hitInfo = bandedGridView1.CalcHitInfo(bandedGridView1.GridControl.PointToClient(Control.MousePosition));
            if (hitInfo.InRow || hitInfo.InRowCell)
            {
                toolStripButton6_Click(sender, e);
            }
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            using var form = new DataAdd2();
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                getData();
            }
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            var entryId = GetFocusedEntryId();
            if (entryId == null)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("請先選擇要編輯的記錄。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            using var form = new DataAdd2(entryId);
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                getData();
            }
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            var entryId = GetFocusedEntryId();
            if (entryId == null)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("請先選擇要刪除的記錄。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            if (XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("確定刪除當前選中的記錄嗎？"),
                    TraditionalChineseHelper.Convert("確認刪除"),
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question) != DialogResult.Yes)
            {
                return;
            }

            DeleteEntry(entryId.Value);
        }

        private void toolStripButtonExportReport_Click(object sender, EventArgs e)
        {
            ExportReport();
        }

        private void toolStripButtonViewReport_Click(object sender, EventArgs e)
        {
            ViewReport();
        }

        private void ExportReport()
        {
            var entryId = GetFocusedEntryId();
            if (entryId == null)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("請先選擇要導出的記錄。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            var focusedRowHandle = bandedGridView1.FocusedRowHandle;
            if (focusedRowHandle < 0)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("沒有可導出的記錄。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            var reportPassword = FetchReportPassword(entryId.Value);

            var parameterNumber = GridDataHelper.GetCellString(bandedGridView1, "ParameterNumber");
            if (string.IsNullOrWhiteSpace(parameterNumber))
            {
                parameterNumber = "Report";
            }

            var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            var fileName = $"{parameterNumber}_{timestamp}.pdf";

            var serverDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReportDirectory);
            Directory.CreateDirectory(serverDirectory);
            var serverFilePath = Path.Combine(serverDirectory, fileName);
            if (File.Exists(serverFilePath))
            {
                File.Delete(serverFilePath);
            }

            var reportSaved = false;

            try
            {
                GenerateSingleRowReport(focusedRowHandle, parameterNumber, serverFilePath, reportPassword);

                using (var dialog = new SaveFileDialog
                {
                    Title = TraditionalChineseHelper.Convert("保存報告"),
                    Filter = TraditionalChineseHelper.Convert("PDF 文件 (*.pdf)|*.pdf"),
                    FileName = TraditionalChineseHelper.Convert(fileName)
                })
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        File.Copy(serverFilePath, dialog.FileName, true);
                        reportSaved = true;
                    }
                    else
                    {
                        return;
                    }
                }

                UpdateReportPath(entryId.Value, serverFilePath);
                bandedGridView1.SetFocusedRowCellValue("FilePath", serverFilePath);

                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("報告導出成功。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"導出報告失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                if (!reportSaved && File.Exists(serverFilePath))
                {
                    File.Delete(serverFilePath);
                }
            }
        }

        private void GenerateSingleRowReport(int rowHandle, string title, string serverFilePath, string? reportPassword)
        {
            var dataList = new List<(string Caption, string Value)>();
            foreach (BandedGridColumn column in bandedGridView1.Columns)
            {
                if (!column.Visible)
                {
                    continue;
                }

                var value = GridDataHelper.GetCellString(bandedGridView1, rowHandle, column.FieldName);
                dataList.Add((column.Caption, value));
            }

            if (dataList.Count == 0)
            {
                throw new InvalidOperationException("无可导出的字段。");
            }

            using var printingSystem = new PrintingSystem();
            using var link = new Link(printingSystem)
            {
                PaperKind = PaperKind.A4,
                Margins = new Margins(40, 40, 60, 60),
                Landscape = false
            };

            link.CreateDetailArea += (_, e) =>
            {
                var graph = e.Graph;
                float top = 0;
                var width = graph.ClientPageSize.Width;
                var captionFont = new Font("微软雅黑", 10F, FontStyle.Bold);
                var valueFont = new Font("微软雅黑", 10F, FontStyle.Regular);

                foreach (var (Caption, Value) in dataList)
                {
                    var captionRect = new RectangleF(0, top, width * 0.35f, 22f);
                    var valueRect = new RectangleF(width * 0.35f + 10, top, width * 0.65f - 10, 22f);

                    graph.StringFormat = new BrickStringFormat(StringAlignment.Near);
                    graph.Font = captionFont;
                    graph.DrawString(Caption, Color.Black, captionRect, DevExpress.XtraPrinting.BorderSide.None);
                    graph.Font = valueFont;
                    graph.DrawString(Value, Color.Black, valueRect, DevExpress.XtraPrinting.BorderSide.None);
                    top += 24f;
                }
            };

            link.CreateDocument();
            var exportOptions = new PdfExportOptions();
            if (!string.IsNullOrEmpty(reportPassword))
            {
                exportOptions.PasswordSecurityOptions.OpenPassword = reportPassword;
                exportOptions.PasswordSecurityOptions.PermissionsPassword = reportPassword;
            }
            link.ExportToPdf(serverFilePath, exportOptions);
        }

        private void ViewReport()
        {
            var filePath = GridDataHelper.GetCellString(bandedGridView1, "FilePath");

            if (string.IsNullOrWhiteSpace(filePath))
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("該記錄尚未生成報告。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
                return;
            }

            if (!File.Exists(filePath))
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert("伺服器上找不到該報告文件。"),
                    TraditionalChineseHelper.Convert("提示"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return;
            }

            try
            {
                var psi = new ProcessStartInfo
                {
                    FileName = filePath,
                    UseShellExecute = true
                };
                Process.Start(psi);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"無法開啟報告：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void UpdateReportPath(int entryId, string serverFilePath)
        {
            try
            {
                using var connection = new MySqlConnection(DatabaseConfig.ConnectionString);
                using var command = new MySqlCommand("UPDATE TestEntries SET FilePath = @FilePath, UpdatedAt = NOW() WHERE EntryID = @EntryID", connection);
                command.Parameters.AddWithValue("@FilePath", serverFilePath);
                command.Parameters.AddWithValue("@EntryID", entryId);

                connection.Open();
                MySqlCollationHelper.EnsureGeneralCollation(connection);
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(
                    TraditionalChineseHelper.Convert($"更新報告路徑失敗：{ex.Message}"),
                    TraditionalChineseHelper.Convert("錯誤"),
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            toolStripButton5_Click(null, null);
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            //toolStripButton6_Click(null, null);
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //toolStripButton7_Click(null, null);
        }

        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //getData();
        }

        private void gridControl1_Click(object sender, EventArgs e)
        {
            // 保留空实现以兼容 Designer
        }
    }
}
